package org.hl7.fhir.r4.model;

/*
  Copyright (c) 2011+, HL7, Inc.
  All rights reserved.
  
  Redistribution and use in source and binary forms, with or without modification, 
  are permitted provided that the following conditions are met:
  
   * Redistributions of source code must retain the above copyright notice, this 
     list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice, 
     this list of conditions and the following disclaimer in the documentation 
     and/or other materials provided with the distribution.
   * Neither the name of HL7 nor the names of its contributors may be used to 
     endorse or promote products derived from this software without specific 
     prior written permission.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
  POSSIBILITY OF SUCH DAMAGE.
  
*/

// Generated on Tue, May 12, 2020 07:26+1000 for FHIR v4.0.1
import java.util.ArrayList;
import java.util.List;

import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
import org.hl7.fhir.utilities.Utilities;

import ca.uhn.fhir.model.api.annotation.Block;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.ResourceDef;

/**
 * An ingredient of a manufactured item or pharmaceutical product.
 */
@ResourceDef(name = "MedicinalProductIngredient", profile = "http://hl7.org/fhir/StructureDefinition/MedicinalProductIngredient")
public class MedicinalProductIngredient extends DomainResource {

  @Block()
  public static class MedicinalProductIngredientSpecifiedSubstanceComponent extends BackboneElement
      implements IBaseBackboneElement {
    /**
     * The specified substance.
     */
    @Child(name = "code", type = {
        CodeableConcept.class }, order = 1, min = 1, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "The specified substance", formalDefinition = "The specified substance.")
    protected CodeableConcept code;

    /**
     * The group of specified substance, e.g. group 1 to 4.
     */
    @Child(name = "group", type = {
        CodeableConcept.class }, order = 2, min = 1, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "The group of specified substance, e.g. group 1 to 4", formalDefinition = "The group of specified substance, e.g. group 1 to 4.")
    protected CodeableConcept group;

    /**
     * Confidentiality level of the specified substance as the ingredient.
     */
    @Child(name = "confidentiality", type = {
        CodeableConcept.class }, order = 3, min = 0, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "Confidentiality level of the specified substance as the ingredient", formalDefinition = "Confidentiality level of the specified substance as the ingredient.")
    protected CodeableConcept confidentiality;

    /**
     * Quantity of the substance or specified substance present in the manufactured
     * item or pharmaceutical product.
     */
    @Child(name = "strength", type = {}, order = 4, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = true)
    @Description(shortDefinition = "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product", formalDefinition = "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product.")
    protected List<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent> strength;

    private static final long serialVersionUID = -272590200L;

    /**
     * Constructor
     */
    public MedicinalProductIngredientSpecifiedSubstanceComponent() {
      super();
    }

    /**
     * Constructor
     */
    public MedicinalProductIngredientSpecifiedSubstanceComponent(CodeableConcept code, CodeableConcept group) {
      super();
      this.code = code;
      this.group = group;
    }

    /**
     * @return {@link #code} (The specified substance.)
     */
    public CodeableConcept getCode() {
      if (this.code == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error("Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceComponent.code");
        else if (Configuration.doAutoCreate())
          this.code = new CodeableConcept(); // cc
      return this.code;
    }

    public boolean hasCode() {
      return this.code != null && !this.code.isEmpty();
    }

    /**
     * @param value {@link #code} (The specified substance.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceComponent setCode(CodeableConcept value) {
      this.code = value;
      return this;
    }

    /**
     * @return {@link #group} (The group of specified substance, e.g. group 1 to 4.)
     */
    public CodeableConcept getGroup() {
      if (this.group == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error("Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceComponent.group");
        else if (Configuration.doAutoCreate())
          this.group = new CodeableConcept(); // cc
      return this.group;
    }

    public boolean hasGroup() {
      return this.group != null && !this.group.isEmpty();
    }

    /**
     * @param value {@link #group} (The group of specified substance, e.g. group 1
     *              to 4.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceComponent setGroup(CodeableConcept value) {
      this.group = value;
      return this;
    }

    /**
     * @return {@link #confidentiality} (Confidentiality level of the specified
     *         substance as the ingredient.)
     */
    public CodeableConcept getConfidentiality() {
      if (this.confidentiality == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceComponent.confidentiality");
        else if (Configuration.doAutoCreate())
          this.confidentiality = new CodeableConcept(); // cc
      return this.confidentiality;
    }

    public boolean hasConfidentiality() {
      return this.confidentiality != null && !this.confidentiality.isEmpty();
    }

    /**
     * @param value {@link #confidentiality} (Confidentiality level of the specified
     *              substance as the ingredient.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceComponent setConfidentiality(CodeableConcept value) {
      this.confidentiality = value;
      return this;
    }

    /**
     * @return {@link #strength} (Quantity of the substance or specified substance
     *         present in the manufactured item or pharmaceutical product.)
     */
    public List<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent> getStrength() {
      if (this.strength == null)
        this.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
      return this.strength;
    }

    /**
     * @return Returns a reference to <code>this</code> for easy method chaining
     */
    public MedicinalProductIngredientSpecifiedSubstanceComponent setStrength(
        List<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent> theStrength) {
      this.strength = theStrength;
      return this;
    }

    public boolean hasStrength() {
      if (this.strength == null)
        return false;
      for (MedicinalProductIngredientSpecifiedSubstanceStrengthComponent item : this.strength)
        if (!item.isEmpty())
          return true;
      return false;
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent addStrength() { // 3
      MedicinalProductIngredientSpecifiedSubstanceStrengthComponent t = new MedicinalProductIngredientSpecifiedSubstanceStrengthComponent();
      if (this.strength == null)
        this.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
      this.strength.add(t);
      return t;
    }

    public MedicinalProductIngredientSpecifiedSubstanceComponent addStrength(
        MedicinalProductIngredientSpecifiedSubstanceStrengthComponent t) { // 3
      if (t == null)
        return this;
      if (this.strength == null)
        this.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
      this.strength.add(t);
      return this;
    }

    /**
     * @return The first repetition of repeating field {@link #strength}, creating
     *         it if it does not already exist
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent getStrengthFirstRep() {
      if (getStrength().isEmpty()) {
        addStrength();
      }
      return getStrength().get(0);
    }

    protected void listChildren(List<Property> children) {
      super.listChildren(children);
      children.add(new Property("code", "CodeableConcept", "The specified substance.", 0, 1, code));
      children.add(new Property("group", "CodeableConcept", "The group of specified substance, e.g. group 1 to 4.", 0,
          1, group));
      children.add(new Property("confidentiality", "CodeableConcept",
          "Confidentiality level of the specified substance as the ingredient.", 0, 1, confidentiality));
      children.add(new Property("strength", "",
          "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product.",
          0, java.lang.Integer.MAX_VALUE, strength));
    }

    @Override
    public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
      switch (_hash) {
      case 3059181:
        /* code */ return new Property("code", "CodeableConcept", "The specified substance.", 0, 1, code);
      case 98629247:
        /* group */ return new Property("group", "CodeableConcept",
            "The group of specified substance, e.g. group 1 to 4.", 0, 1, group);
      case -1923018202:
        /* confidentiality */ return new Property("confidentiality", "CodeableConcept",
            "Confidentiality level of the specified substance as the ingredient.", 0, 1, confidentiality);
      case 1791316033:
        /* strength */ return new Property("strength", "",
            "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product.",
            0, java.lang.Integer.MAX_VALUE, strength);
      default:
        return super.getNamedProperty(_hash, _name, _checkValid);
      }

    }

    @Override
    public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
      switch (hash) {
      case 3059181:
        /* code */ return this.code == null ? new Base[0] : new Base[] { this.code }; // CodeableConcept
      case 98629247:
        /* group */ return this.group == null ? new Base[0] : new Base[] { this.group }; // CodeableConcept
      case -1923018202:
        /* confidentiality */ return this.confidentiality == null ? new Base[0] : new Base[] { this.confidentiality }; // CodeableConcept
      case 1791316033:
        /* strength */ return this.strength == null ? new Base[0]
            : this.strength.toArray(new Base[this.strength.size()]); // MedicinalProductIngredientSpecifiedSubstanceStrengthComponent
      default:
        return super.getProperty(hash, name, checkValid);
      }

    }

    @Override
    public Base setProperty(int hash, String name, Base value) throws FHIRException {
      switch (hash) {
      case 3059181: // code
        this.code = castToCodeableConcept(value); // CodeableConcept
        return value;
      case 98629247: // group
        this.group = castToCodeableConcept(value); // CodeableConcept
        return value;
      case -1923018202: // confidentiality
        this.confidentiality = castToCodeableConcept(value); // CodeableConcept
        return value;
      case 1791316033: // strength
        this.getStrength().add((MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) value); // MedicinalProductIngredientSpecifiedSubstanceStrengthComponent
        return value;
      default:
        return super.setProperty(hash, name, value);
      }

    }

    @Override
    public Base setProperty(String name, Base value) throws FHIRException {
      if (name.equals("code")) {
        this.code = castToCodeableConcept(value); // CodeableConcept
      } else if (name.equals("group")) {
        this.group = castToCodeableConcept(value); // CodeableConcept
      } else if (name.equals("confidentiality")) {
        this.confidentiality = castToCodeableConcept(value); // CodeableConcept
      } else if (name.equals("strength")) {
        this.getStrength().add((MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) value);
      } else
        return super.setProperty(name, value);
      return value;
    }

  @Override
  public void removeChild(String name, Base value) throws FHIRException {
      if (name.equals("code")) {
        this.code = null;
      } else if (name.equals("group")) {
        this.group = null;
      } else if (name.equals("confidentiality")) {
        this.confidentiality = null;
      } else if (name.equals("strength")) {
        this.getStrength().remove((MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) value);
      } else
        super.removeChild(name, value);
      
    }

    @Override
    public Base makeProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 3059181:
        return getCode();
      case 98629247:
        return getGroup();
      case -1923018202:
        return getConfidentiality();
      case 1791316033:
        return addStrength();
      default:
        return super.makeProperty(hash, name);
      }

    }

    @Override
    public String[] getTypesForProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 3059181:
        /* code */ return new String[] { "CodeableConcept" };
      case 98629247:
        /* group */ return new String[] { "CodeableConcept" };
      case -1923018202:
        /* confidentiality */ return new String[] { "CodeableConcept" };
      case 1791316033:
        /* strength */ return new String[] {};
      default:
        return super.getTypesForProperty(hash, name);
      }

    }

    @Override
    public Base addChild(String name) throws FHIRException {
      if (name.equals("code")) {
        this.code = new CodeableConcept();
        return this.code;
      } else if (name.equals("group")) {
        this.group = new CodeableConcept();
        return this.group;
      } else if (name.equals("confidentiality")) {
        this.confidentiality = new CodeableConcept();
        return this.confidentiality;
      } else if (name.equals("strength")) {
        return addStrength();
      } else
        return super.addChild(name);
    }

    public MedicinalProductIngredientSpecifiedSubstanceComponent copy() {
      MedicinalProductIngredientSpecifiedSubstanceComponent dst = new MedicinalProductIngredientSpecifiedSubstanceComponent();
      copyValues(dst);
      return dst;
    }

    public void copyValues(MedicinalProductIngredientSpecifiedSubstanceComponent dst) {
      super.copyValues(dst);
      dst.code = code == null ? null : code.copy();
      dst.group = group == null ? null : group.copy();
      dst.confidentiality = confidentiality == null ? null : confidentiality.copy();
      if (strength != null) {
        dst.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
        for (MedicinalProductIngredientSpecifiedSubstanceStrengthComponent i : strength)
          dst.strength.add(i.copy());
      }
      ;
    }

    @Override
    public boolean equalsDeep(Base other_) {
      if (!super.equalsDeep(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSpecifiedSubstanceComponent))
        return false;
      MedicinalProductIngredientSpecifiedSubstanceComponent o = (MedicinalProductIngredientSpecifiedSubstanceComponent) other_;
      return compareDeep(code, o.code, true) && compareDeep(group, o.group, true)
          && compareDeep(confidentiality, o.confidentiality, true) && compareDeep(strength, o.strength, true);
    }

    @Override
    public boolean equalsShallow(Base other_) {
      if (!super.equalsShallow(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSpecifiedSubstanceComponent))
        return false;
      MedicinalProductIngredientSpecifiedSubstanceComponent o = (MedicinalProductIngredientSpecifiedSubstanceComponent) other_;
      return true;
    }

    public boolean isEmpty() {
      return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(code, group, confidentiality, strength);
    }

    public String fhirType() {
      return "MedicinalProductIngredient.specifiedSubstance";

    }

  }

  @Block()
  public static class MedicinalProductIngredientSpecifiedSubstanceStrengthComponent extends BackboneElement
      implements IBaseBackboneElement {
    /**
     * The quantity of substance in the unit of presentation, or in the volume (or
     * mass) of the single pharmaceutical product or manufactured item.
     */
    @Child(name = "presentation", type = { Ratio.class }, order = 1, min = 1, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "The quantity of substance in the unit of presentation, or in the volume (or mass) of the single pharmaceutical product or manufactured item", formalDefinition = "The quantity of substance in the unit of presentation, or in the volume (or mass) of the single pharmaceutical product or manufactured item.")
    protected Ratio presentation;

    /**
     * A lower limit for the quantity of substance in the unit of presentation. For
     * use when there is a range of strengths, this is the lower limit, with the
     * presentation attribute becoming the upper limit.
     */
    @Child(name = "presentationLowLimit", type = {
        Ratio.class }, order = 2, min = 0, max = 1, modifier = true, summary = true)
    @Description(shortDefinition = "A lower limit for the quantity of substance in the unit of presentation. For use when there is a range of strengths, this is the lower limit, with the presentation attribute becoming the upper limit", formalDefinition = "A lower limit for the quantity of substance in the unit of presentation. For use when there is a range of strengths, this is the lower limit, with the presentation attribute becoming the upper limit.")
    protected Ratio presentationLowLimit;

    /**
     * The strength per unitary volume (or mass).
     */
    @Child(name = "concentration", type = {
        Ratio.class }, order = 3, min = 0, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "The strength per unitary volume (or mass)", formalDefinition = "The strength per unitary volume (or mass).")
    protected Ratio concentration;

    /**
     * A lower limit for the strength per unitary volume (or mass), for when there
     * is a range. The concentration attribute then becomes the upper limit.
     */
    @Child(name = "concentrationLowLimit", type = {
        Ratio.class }, order = 4, min = 0, max = 1, modifier = true, summary = true)
    @Description(shortDefinition = "A lower limit for the strength per unitary volume (or mass), for when there is a range. The concentration attribute then becomes the upper limit", formalDefinition = "A lower limit for the strength per unitary volume (or mass), for when there is a range. The concentration attribute then becomes the upper limit.")
    protected Ratio concentrationLowLimit;

    /**
     * For when strength is measured at a particular point or distance.
     */
    @Child(name = "measurementPoint", type = {
        StringType.class }, order = 5, min = 0, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "For when strength is measured at a particular point or distance", formalDefinition = "For when strength is measured at a particular point or distance.")
    protected StringType measurementPoint;

    /**
     * The country or countries for which the strength range applies.
     */
    @Child(name = "country", type = {
        CodeableConcept.class }, order = 6, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = true)
    @Description(shortDefinition = "The country or countries for which the strength range applies", formalDefinition = "The country or countries for which the strength range applies.")
    protected List<CodeableConcept> country;

    /**
     * Strength expressed in terms of a reference substance.
     */
    @Child(name = "referenceStrength", type = {}, order = 7, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = true)
    @Description(shortDefinition = "Strength expressed in terms of a reference substance", formalDefinition = "Strength expressed in terms of a reference substance.")
    protected List<MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent> referenceStrength;

    private static final long serialVersionUID = 1981438822L;

    /**
     * Constructor
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent() {
      super();
    }

    /**
     * Constructor
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent(Ratio presentation) {
      super();
      this.presentation = presentation;
    }

    /**
     * @return {@link #presentation} (The quantity of substance in the unit of
     *         presentation, or in the volume (or mass) of the single pharmaceutical
     *         product or manufactured item.)
     */
    public Ratio getPresentation() {
      if (this.presentation == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthComponent.presentation");
        else if (Configuration.doAutoCreate())
          this.presentation = new Ratio(); // cc
      return this.presentation;
    }

    public boolean hasPresentation() {
      return this.presentation != null && !this.presentation.isEmpty();
    }

    /**
     * @param value {@link #presentation} (The quantity of substance in the unit of
     *              presentation, or in the volume (or mass) of the single
     *              pharmaceutical product or manufactured item.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setPresentation(Ratio value) {
      this.presentation = value;
      return this;
    }

    /**
     * @return {@link #presentationLowLimit} (A lower limit for the quantity of
     *         substance in the unit of presentation. For use when there is a range
     *         of strengths, this is the lower limit, with the presentation
     *         attribute becoming the upper limit.)
     */
    public Ratio getPresentationLowLimit() {
      if (this.presentationLowLimit == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthComponent.presentationLowLimit");
        else if (Configuration.doAutoCreate())
          this.presentationLowLimit = new Ratio(); // cc
      return this.presentationLowLimit;
    }

    public boolean hasPresentationLowLimit() {
      return this.presentationLowLimit != null && !this.presentationLowLimit.isEmpty();
    }

    /**
     * @param value {@link #presentationLowLimit} (A lower limit for the quantity of
     *              substance in the unit of presentation. For use when there is a
     *              range of strengths, this is the lower limit, with the
     *              presentation attribute becoming the upper limit.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setPresentationLowLimit(Ratio value) {
      this.presentationLowLimit = value;
      return this;
    }

    /**
     * @return {@link #concentration} (The strength per unitary volume (or mass).)
     */
    public Ratio getConcentration() {
      if (this.concentration == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthComponent.concentration");
        else if (Configuration.doAutoCreate())
          this.concentration = new Ratio(); // cc
      return this.concentration;
    }

    public boolean hasConcentration() {
      return this.concentration != null && !this.concentration.isEmpty();
    }

    /**
     * @param value {@link #concentration} (The strength per unitary volume (or
     *              mass).)
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setConcentration(Ratio value) {
      this.concentration = value;
      return this;
    }

    /**
     * @return {@link #concentrationLowLimit} (A lower limit for the strength per
     *         unitary volume (or mass), for when there is a range. The
     *         concentration attribute then becomes the upper limit.)
     */
    public Ratio getConcentrationLowLimit() {
      if (this.concentrationLowLimit == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthComponent.concentrationLowLimit");
        else if (Configuration.doAutoCreate())
          this.concentrationLowLimit = new Ratio(); // cc
      return this.concentrationLowLimit;
    }

    public boolean hasConcentrationLowLimit() {
      return this.concentrationLowLimit != null && !this.concentrationLowLimit.isEmpty();
    }

    /**
     * @param value {@link #concentrationLowLimit} (A lower limit for the strength
     *              per unitary volume (or mass), for when there is a range. The
     *              concentration attribute then becomes the upper limit.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setConcentrationLowLimit(Ratio value) {
      this.concentrationLowLimit = value;
      return this;
    }

    /**
     * @return {@link #measurementPoint} (For when strength is measured at a
     *         particular point or distance.). This is the underlying object with
     *         id, value and extensions. The accessor "getMeasurementPoint" gives
     *         direct access to the value
     */
    public StringType getMeasurementPointElement() {
      if (this.measurementPoint == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthComponent.measurementPoint");
        else if (Configuration.doAutoCreate())
          this.measurementPoint = new StringType(); // bb
      return this.measurementPoint;
    }

    public boolean hasMeasurementPointElement() {
      return this.measurementPoint != null && !this.measurementPoint.isEmpty();
    }

    public boolean hasMeasurementPoint() {
      return this.measurementPoint != null && !this.measurementPoint.isEmpty();
    }

    /**
     * @param value {@link #measurementPoint} (For when strength is measured at a
     *              particular point or distance.). This is the underlying object
     *              with id, value and extensions. The accessor
     *              "getMeasurementPoint" gives direct access to the value
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setMeasurementPointElement(StringType value) {
      this.measurementPoint = value;
      return this;
    }

    /**
     * @return For when strength is measured at a particular point or distance.
     */
    public String getMeasurementPoint() {
      return this.measurementPoint == null ? null : this.measurementPoint.getValue();
    }

    /**
     * @param value For when strength is measured at a particular point or distance.
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setMeasurementPoint(String value) {
      if (Utilities.noString(value))
        this.measurementPoint = null;
      else {
        if (this.measurementPoint == null)
          this.measurementPoint = new StringType();
        this.measurementPoint.setValue(value);
      }
      return this;
    }

    /**
     * @return {@link #country} (The country or countries for which the strength
     *         range applies.)
     */
    public List<CodeableConcept> getCountry() {
      if (this.country == null)
        this.country = new ArrayList<CodeableConcept>();
      return this.country;
    }

    /**
     * @return Returns a reference to <code>this</code> for easy method chaining
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setCountry(List<CodeableConcept> theCountry) {
      this.country = theCountry;
      return this;
    }

    public boolean hasCountry() {
      if (this.country == null)
        return false;
      for (CodeableConcept item : this.country)
        if (!item.isEmpty())
          return true;
      return false;
    }

    public CodeableConcept addCountry() { // 3
      CodeableConcept t = new CodeableConcept();
      if (this.country == null)
        this.country = new ArrayList<CodeableConcept>();
      this.country.add(t);
      return t;
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent addCountry(CodeableConcept t) { // 3
      if (t == null)
        return this;
      if (this.country == null)
        this.country = new ArrayList<CodeableConcept>();
      this.country.add(t);
      return this;
    }

    /**
     * @return The first repetition of repeating field {@link #country}, creating it
     *         if it does not already exist
     */
    public CodeableConcept getCountryFirstRep() {
      if (getCountry().isEmpty()) {
        addCountry();
      }
      return getCountry().get(0);
    }

    /**
     * @return {@link #referenceStrength} (Strength expressed in terms of a
     *         reference substance.)
     */
    public List<MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent> getReferenceStrength() {
      if (this.referenceStrength == null)
        this.referenceStrength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent>();
      return this.referenceStrength;
    }

    /**
     * @return Returns a reference to <code>this</code> for easy method chaining
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent setReferenceStrength(
        List<MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent> theReferenceStrength) {
      this.referenceStrength = theReferenceStrength;
      return this;
    }

    public boolean hasReferenceStrength() {
      if (this.referenceStrength == null)
        return false;
      for (MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent item : this.referenceStrength)
        if (!item.isEmpty())
          return true;
      return false;
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent addReferenceStrength() { // 3
      MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent t = new MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent();
      if (this.referenceStrength == null)
        this.referenceStrength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent>();
      this.referenceStrength.add(t);
      return t;
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent addReferenceStrength(
        MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent t) { // 3
      if (t == null)
        return this;
      if (this.referenceStrength == null)
        this.referenceStrength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent>();
      this.referenceStrength.add(t);
      return this;
    }

    /**
     * @return The first repetition of repeating field {@link #referenceStrength},
     *         creating it if it does not already exist
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent getReferenceStrengthFirstRep() {
      if (getReferenceStrength().isEmpty()) {
        addReferenceStrength();
      }
      return getReferenceStrength().get(0);
    }

    protected void listChildren(List<Property> children) {
      super.listChildren(children);
      children.add(new Property("presentation", "Ratio",
          "The quantity of substance in the unit of presentation, or in the volume (or mass) of the single pharmaceutical product or manufactured item.",
          0, 1, presentation));
      children.add(new Property("presentationLowLimit", "Ratio",
          "A lower limit for the quantity of substance in the unit of presentation. For use when there is a range of strengths, this is the lower limit, with the presentation attribute becoming the upper limit.",
          0, 1, presentationLowLimit));
      children.add(
          new Property("concentration", "Ratio", "The strength per unitary volume (or mass).", 0, 1, concentration));
      children.add(new Property("concentrationLowLimit", "Ratio",
          "A lower limit for the strength per unitary volume (or mass), for when there is a range. The concentration attribute then becomes the upper limit.",
          0, 1, concentrationLowLimit));
      children.add(new Property("measurementPoint", "string",
          "For when strength is measured at a particular point or distance.", 0, 1, measurementPoint));
      children.add(new Property("country", "CodeableConcept",
          "The country or countries for which the strength range applies.", 0, java.lang.Integer.MAX_VALUE, country));
      children.add(new Property("referenceStrength", "", "Strength expressed in terms of a reference substance.", 0,
          java.lang.Integer.MAX_VALUE, referenceStrength));
    }

    @Override
    public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
      switch (_hash) {
      case 696975130:
        /* presentation */ return new Property("presentation", "Ratio",
            "The quantity of substance in the unit of presentation, or in the volume (or mass) of the single pharmaceutical product or manufactured item.",
            0, 1, presentation);
      case -819112447:
        /* presentationLowLimit */ return new Property("presentationLowLimit", "Ratio",
            "A lower limit for the quantity of substance in the unit of presentation. For use when there is a range of strengths, this is the lower limit, with the presentation attribute becoming the upper limit.",
            0, 1, presentationLowLimit);
      case -410557331:
        /* concentration */ return new Property("concentration", "Ratio", "The strength per unitary volume (or mass).",
            0, 1, concentration);
      case -484132780:
        /* concentrationLowLimit */ return new Property("concentrationLowLimit", "Ratio",
            "A lower limit for the strength per unitary volume (or mass), for when there is a range. The concentration attribute then becomes the upper limit.",
            0, 1, concentrationLowLimit);
      case 235437876:
        /* measurementPoint */ return new Property("measurementPoint", "string",
            "For when strength is measured at a particular point or distance.", 0, 1, measurementPoint);
      case 957831062:
        /* country */ return new Property("country", "CodeableConcept",
            "The country or countries for which the strength range applies.", 0, java.lang.Integer.MAX_VALUE, country);
      case 1943566508:
        /* referenceStrength */ return new Property("referenceStrength", "",
            "Strength expressed in terms of a reference substance.", 0, java.lang.Integer.MAX_VALUE, referenceStrength);
      default:
        return super.getNamedProperty(_hash, _name, _checkValid);
      }

    }

    @Override
    public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
      switch (hash) {
      case 696975130:
        /* presentation */ return this.presentation == null ? new Base[0] : new Base[] { this.presentation }; // Ratio
      case -819112447:
        /* presentationLowLimit */ return this.presentationLowLimit == null ? new Base[0]
            : new Base[] { this.presentationLowLimit }; // Ratio
      case -410557331:
        /* concentration */ return this.concentration == null ? new Base[0] : new Base[] { this.concentration }; // Ratio
      case -484132780:
        /* concentrationLowLimit */ return this.concentrationLowLimit == null ? new Base[0]
            : new Base[] { this.concentrationLowLimit }; // Ratio
      case 235437876:
        /* measurementPoint */ return this.measurementPoint == null ? new Base[0]
            : new Base[] { this.measurementPoint }; // StringType
      case 957831062:
        /* country */ return this.country == null ? new Base[0] : this.country.toArray(new Base[this.country.size()]); // CodeableConcept
      case 1943566508:
        /* referenceStrength */ return this.referenceStrength == null ? new Base[0]
            : this.referenceStrength.toArray(new Base[this.referenceStrength.size()]); // MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent
      default:
        return super.getProperty(hash, name, checkValid);
      }

    }

    @Override
    public Base setProperty(int hash, String name, Base value) throws FHIRException {
      switch (hash) {
      case 696975130: // presentation
        this.presentation = castToRatio(value); // Ratio
        return value;
      case -819112447: // presentationLowLimit
        this.presentationLowLimit = castToRatio(value); // Ratio
        return value;
      case -410557331: // concentration
        this.concentration = castToRatio(value); // Ratio
        return value;
      case -484132780: // concentrationLowLimit
        this.concentrationLowLimit = castToRatio(value); // Ratio
        return value;
      case 235437876: // measurementPoint
        this.measurementPoint = castToString(value); // StringType
        return value;
      case 957831062: // country
        this.getCountry().add(castToCodeableConcept(value)); // CodeableConcept
        return value;
      case 1943566508: // referenceStrength
        this.getReferenceStrength()
            .add((MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent) value); // MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent
        return value;
      default:
        return super.setProperty(hash, name, value);
      }

    }

    @Override
    public Base setProperty(String name, Base value) throws FHIRException {
      if (name.equals("presentation")) {
        this.presentation = castToRatio(value); // Ratio
      } else if (name.equals("presentationLowLimit")) {
        this.presentationLowLimit = castToRatio(value); // Ratio
      } else if (name.equals("concentration")) {
        this.concentration = castToRatio(value); // Ratio
      } else if (name.equals("concentrationLowLimit")) {
        this.concentrationLowLimit = castToRatio(value); // Ratio
      } else if (name.equals("measurementPoint")) {
        this.measurementPoint = castToString(value); // StringType
      } else if (name.equals("country")) {
        this.getCountry().add(castToCodeableConcept(value));
      } else if (name.equals("referenceStrength")) {
        this.getReferenceStrength()
            .add((MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent) value);
      } else
        return super.setProperty(name, value);
      return value;
    }

  @Override
  public void removeChild(String name, Base value) throws FHIRException {
      if (name.equals("presentation")) {
        this.presentation = null;
      } else if (name.equals("presentationLowLimit")) {
        this.presentationLowLimit = null;
      } else if (name.equals("concentration")) {
        this.concentration = null;
      } else if (name.equals("concentrationLowLimit")) {
        this.concentrationLowLimit = null;
      } else if (name.equals("measurementPoint")) {
        this.measurementPoint = null;
      } else if (name.equals("country")) {
        this.getCountry().remove(castToCodeableConcept(value));
      } else if (name.equals("referenceStrength")) {
        this.getReferenceStrength()
            .remove((MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent) value);
      } else
        super.removeChild(name, value);
      
    }

    @Override
    public Base makeProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 696975130:
        return getPresentation();
      case -819112447:
        return getPresentationLowLimit();
      case -410557331:
        return getConcentration();
      case -484132780:
        return getConcentrationLowLimit();
      case 235437876:
        return getMeasurementPointElement();
      case 957831062:
        return addCountry();
      case 1943566508:
        return addReferenceStrength();
      default:
        return super.makeProperty(hash, name);
      }

    }

    @Override
    public String[] getTypesForProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 696975130:
        /* presentation */ return new String[] { "Ratio" };
      case -819112447:
        /* presentationLowLimit */ return new String[] { "Ratio" };
      case -410557331:
        /* concentration */ return new String[] { "Ratio" };
      case -484132780:
        /* concentrationLowLimit */ return new String[] { "Ratio" };
      case 235437876:
        /* measurementPoint */ return new String[] { "string" };
      case 957831062:
        /* country */ return new String[] { "CodeableConcept" };
      case 1943566508:
        /* referenceStrength */ return new String[] {};
      default:
        return super.getTypesForProperty(hash, name);
      }

    }

    @Override
    public Base addChild(String name) throws FHIRException {
      if (name.equals("presentation")) {
        this.presentation = new Ratio();
        return this.presentation;
      } else if (name.equals("presentationLowLimit")) {
        this.presentationLowLimit = new Ratio();
        return this.presentationLowLimit;
      } else if (name.equals("concentration")) {
        this.concentration = new Ratio();
        return this.concentration;
      } else if (name.equals("concentrationLowLimit")) {
        this.concentrationLowLimit = new Ratio();
        return this.concentrationLowLimit;
      } else if (name.equals("measurementPoint")) {
        throw new FHIRException("Cannot call addChild on a singleton property MedicinalProductIngredient.measurementPoint");
      } else if (name.equals("country")) {
        return addCountry();
      } else if (name.equals("referenceStrength")) {
        return addReferenceStrength();
      } else
        return super.addChild(name);
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent copy() {
      MedicinalProductIngredientSpecifiedSubstanceStrengthComponent dst = new MedicinalProductIngredientSpecifiedSubstanceStrengthComponent();
      copyValues(dst);
      return dst;
    }

    public void copyValues(MedicinalProductIngredientSpecifiedSubstanceStrengthComponent dst) {
      super.copyValues(dst);
      dst.presentation = presentation == null ? null : presentation.copy();
      dst.presentationLowLimit = presentationLowLimit == null ? null : presentationLowLimit.copy();
      dst.concentration = concentration == null ? null : concentration.copy();
      dst.concentrationLowLimit = concentrationLowLimit == null ? null : concentrationLowLimit.copy();
      dst.measurementPoint = measurementPoint == null ? null : measurementPoint.copy();
      if (country != null) {
        dst.country = new ArrayList<CodeableConcept>();
        for (CodeableConcept i : country)
          dst.country.add(i.copy());
      }
      ;
      if (referenceStrength != null) {
        dst.referenceStrength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent>();
        for (MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent i : referenceStrength)
          dst.referenceStrength.add(i.copy());
      }
      ;
    }

    @Override
    public boolean equalsDeep(Base other_) {
      if (!super.equalsDeep(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSpecifiedSubstanceStrengthComponent))
        return false;
      MedicinalProductIngredientSpecifiedSubstanceStrengthComponent o = (MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) other_;
      return compareDeep(presentation, o.presentation, true)
          && compareDeep(presentationLowLimit, o.presentationLowLimit, true)
          && compareDeep(concentration, o.concentration, true)
          && compareDeep(concentrationLowLimit, o.concentrationLowLimit, true)
          && compareDeep(measurementPoint, o.measurementPoint, true) && compareDeep(country, o.country, true)
          && compareDeep(referenceStrength, o.referenceStrength, true);
    }

    @Override
    public boolean equalsShallow(Base other_) {
      if (!super.equalsShallow(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSpecifiedSubstanceStrengthComponent))
        return false;
      MedicinalProductIngredientSpecifiedSubstanceStrengthComponent o = (MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) other_;
      return compareValues(measurementPoint, o.measurementPoint, true);
    }

    public boolean isEmpty() {
      return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(presentation, presentationLowLimit, concentration,
          concentrationLowLimit, measurementPoint, country, referenceStrength);
    }

    public String fhirType() {
      return "MedicinalProductIngredient.specifiedSubstance.strength";

    }

  }

  @Block()
  public static class MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent
      extends BackboneElement implements IBaseBackboneElement {
    /**
     * Relevant reference substance.
     */
    @Child(name = "substance", type = {
        CodeableConcept.class }, order = 1, min = 0, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "Relevant reference substance", formalDefinition = "Relevant reference substance.")
    protected CodeableConcept substance;

    /**
     * Strength expressed in terms of a reference substance.
     */
    @Child(name = "strength", type = { Ratio.class }, order = 2, min = 1, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "Strength expressed in terms of a reference substance", formalDefinition = "Strength expressed in terms of a reference substance.")
    protected Ratio strength;

    /**
     * Strength expressed in terms of a reference substance.
     */
    @Child(name = "strengthLowLimit", type = {
        Ratio.class }, order = 3, min = 0, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "Strength expressed in terms of a reference substance", formalDefinition = "Strength expressed in terms of a reference substance.")
    protected Ratio strengthLowLimit;

    /**
     * For when strength is measured at a particular point or distance.
     */
    @Child(name = "measurementPoint", type = {
        StringType.class }, order = 4, min = 0, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "For when strength is measured at a particular point or distance", formalDefinition = "For when strength is measured at a particular point or distance.")
    protected StringType measurementPoint;

    /**
     * The country or countries for which the strength range applies.
     */
    @Child(name = "country", type = {
        CodeableConcept.class }, order = 5, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = true)
    @Description(shortDefinition = "The country or countries for which the strength range applies", formalDefinition = "The country or countries for which the strength range applies.")
    protected List<CodeableConcept> country;

    private static final long serialVersionUID = -839485716L;

    /**
     * Constructor
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent() {
      super();
    }

    /**
     * Constructor
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent(Ratio strength) {
      super();
      this.strength = strength;
    }

    /**
     * @return {@link #substance} (Relevant reference substance.)
     */
    public CodeableConcept getSubstance() {
      if (this.substance == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent.substance");
        else if (Configuration.doAutoCreate())
          this.substance = new CodeableConcept(); // cc
      return this.substance;
    }

    public boolean hasSubstance() {
      return this.substance != null && !this.substance.isEmpty();
    }

    /**
     * @param value {@link #substance} (Relevant reference substance.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent setSubstance(
        CodeableConcept value) {
      this.substance = value;
      return this;
    }

    /**
     * @return {@link #strength} (Strength expressed in terms of a reference
     *         substance.)
     */
    public Ratio getStrength() {
      if (this.strength == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent.strength");
        else if (Configuration.doAutoCreate())
          this.strength = new Ratio(); // cc
      return this.strength;
    }

    public boolean hasStrength() {
      return this.strength != null && !this.strength.isEmpty();
    }

    /**
     * @param value {@link #strength} (Strength expressed in terms of a reference
     *              substance.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent setStrength(Ratio value) {
      this.strength = value;
      return this;
    }

    /**
     * @return {@link #strengthLowLimit} (Strength expressed in terms of a reference
     *         substance.)
     */
    public Ratio getStrengthLowLimit() {
      if (this.strengthLowLimit == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent.strengthLowLimit");
        else if (Configuration.doAutoCreate())
          this.strengthLowLimit = new Ratio(); // cc
      return this.strengthLowLimit;
    }

    public boolean hasStrengthLowLimit() {
      return this.strengthLowLimit != null && !this.strengthLowLimit.isEmpty();
    }

    /**
     * @param value {@link #strengthLowLimit} (Strength expressed in terms of a
     *              reference substance.)
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent setStrengthLowLimit(
        Ratio value) {
      this.strengthLowLimit = value;
      return this;
    }

    /**
     * @return {@link #measurementPoint} (For when strength is measured at a
     *         particular point or distance.). This is the underlying object with
     *         id, value and extensions. The accessor "getMeasurementPoint" gives
     *         direct access to the value
     */
    public StringType getMeasurementPointElement() {
      if (this.measurementPoint == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error(
              "Attempt to auto-create MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent.measurementPoint");
        else if (Configuration.doAutoCreate())
          this.measurementPoint = new StringType(); // bb
      return this.measurementPoint;
    }

    public boolean hasMeasurementPointElement() {
      return this.measurementPoint != null && !this.measurementPoint.isEmpty();
    }

    public boolean hasMeasurementPoint() {
      return this.measurementPoint != null && !this.measurementPoint.isEmpty();
    }

    /**
     * @param value {@link #measurementPoint} (For when strength is measured at a
     *              particular point or distance.). This is the underlying object
     *              with id, value and extensions. The accessor
     *              "getMeasurementPoint" gives direct access to the value
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent setMeasurementPointElement(
        StringType value) {
      this.measurementPoint = value;
      return this;
    }

    /**
     * @return For when strength is measured at a particular point or distance.
     */
    public String getMeasurementPoint() {
      return this.measurementPoint == null ? null : this.measurementPoint.getValue();
    }

    /**
     * @param value For when strength is measured at a particular point or distance.
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent setMeasurementPoint(
        String value) {
      if (Utilities.noString(value))
        this.measurementPoint = null;
      else {
        if (this.measurementPoint == null)
          this.measurementPoint = new StringType();
        this.measurementPoint.setValue(value);
      }
      return this;
    }

    /**
     * @return {@link #country} (The country or countries for which the strength
     *         range applies.)
     */
    public List<CodeableConcept> getCountry() {
      if (this.country == null)
        this.country = new ArrayList<CodeableConcept>();
      return this.country;
    }

    /**
     * @return Returns a reference to <code>this</code> for easy method chaining
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent setCountry(
        List<CodeableConcept> theCountry) {
      this.country = theCountry;
      return this;
    }

    public boolean hasCountry() {
      if (this.country == null)
        return false;
      for (CodeableConcept item : this.country)
        if (!item.isEmpty())
          return true;
      return false;
    }

    public CodeableConcept addCountry() { // 3
      CodeableConcept t = new CodeableConcept();
      if (this.country == null)
        this.country = new ArrayList<CodeableConcept>();
      this.country.add(t);
      return t;
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent addCountry(
        CodeableConcept t) { // 3
      if (t == null)
        return this;
      if (this.country == null)
        this.country = new ArrayList<CodeableConcept>();
      this.country.add(t);
      return this;
    }

    /**
     * @return The first repetition of repeating field {@link #country}, creating it
     *         if it does not already exist
     */
    public CodeableConcept getCountryFirstRep() {
      if (getCountry().isEmpty()) {
        addCountry();
      }
      return getCountry().get(0);
    }

    protected void listChildren(List<Property> children) {
      super.listChildren(children);
      children.add(new Property("substance", "CodeableConcept", "Relevant reference substance.", 0, 1, substance));
      children.add(
          new Property("strength", "Ratio", "Strength expressed in terms of a reference substance.", 0, 1, strength));
      children.add(new Property("strengthLowLimit", "Ratio", "Strength expressed in terms of a reference substance.", 0,
          1, strengthLowLimit));
      children.add(new Property("measurementPoint", "string",
          "For when strength is measured at a particular point or distance.", 0, 1, measurementPoint));
      children.add(new Property("country", "CodeableConcept",
          "The country or countries for which the strength range applies.", 0, java.lang.Integer.MAX_VALUE, country));
    }

    @Override
    public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
      switch (_hash) {
      case 530040176:
        /* substance */ return new Property("substance", "CodeableConcept", "Relevant reference substance.", 0, 1,
            substance);
      case 1791316033:
        /* strength */ return new Property("strength", "Ratio", "Strength expressed in terms of a reference substance.",
            0, 1, strength);
      case 1945341992:
        /* strengthLowLimit */ return new Property("strengthLowLimit", "Ratio",
            "Strength expressed in terms of a reference substance.", 0, 1, strengthLowLimit);
      case 235437876:
        /* measurementPoint */ return new Property("measurementPoint", "string",
            "For when strength is measured at a particular point or distance.", 0, 1, measurementPoint);
      case 957831062:
        /* country */ return new Property("country", "CodeableConcept",
            "The country or countries for which the strength range applies.", 0, java.lang.Integer.MAX_VALUE, country);
      default:
        return super.getNamedProperty(_hash, _name, _checkValid);
      }

    }

    @Override
    public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
      switch (hash) {
      case 530040176:
        /* substance */ return this.substance == null ? new Base[0] : new Base[] { this.substance }; // CodeableConcept
      case 1791316033:
        /* strength */ return this.strength == null ? new Base[0] : new Base[] { this.strength }; // Ratio
      case 1945341992:
        /* strengthLowLimit */ return this.strengthLowLimit == null ? new Base[0]
            : new Base[] { this.strengthLowLimit }; // Ratio
      case 235437876:
        /* measurementPoint */ return this.measurementPoint == null ? new Base[0]
            : new Base[] { this.measurementPoint }; // StringType
      case 957831062:
        /* country */ return this.country == null ? new Base[0] : this.country.toArray(new Base[this.country.size()]); // CodeableConcept
      default:
        return super.getProperty(hash, name, checkValid);
      }

    }

    @Override
    public Base setProperty(int hash, String name, Base value) throws FHIRException {
      switch (hash) {
      case 530040176: // substance
        this.substance = castToCodeableConcept(value); // CodeableConcept
        return value;
      case 1791316033: // strength
        this.strength = castToRatio(value); // Ratio
        return value;
      case 1945341992: // strengthLowLimit
        this.strengthLowLimit = castToRatio(value); // Ratio
        return value;
      case 235437876: // measurementPoint
        this.measurementPoint = castToString(value); // StringType
        return value;
      case 957831062: // country
        this.getCountry().add(castToCodeableConcept(value)); // CodeableConcept
        return value;
      default:
        return super.setProperty(hash, name, value);
      }

    }

    @Override
    public Base setProperty(String name, Base value) throws FHIRException {
      if (name.equals("substance")) {
        this.substance = castToCodeableConcept(value); // CodeableConcept
      } else if (name.equals("strength")) {
        this.strength = castToRatio(value); // Ratio
      } else if (name.equals("strengthLowLimit")) {
        this.strengthLowLimit = castToRatio(value); // Ratio
      } else if (name.equals("measurementPoint")) {
        this.measurementPoint = castToString(value); // StringType
      } else if (name.equals("country")) {
        this.getCountry().add(castToCodeableConcept(value));
      } else
        return super.setProperty(name, value);
      return value;
    }

  @Override
  public void removeChild(String name, Base value) throws FHIRException {
      if (name.equals("substance")) {
        this.substance = null;
      } else if (name.equals("strength")) {
        this.strength = null;
      } else if (name.equals("strengthLowLimit")) {
        this.strengthLowLimit = null;
      } else if (name.equals("measurementPoint")) {
        this.measurementPoint = null;
      } else if (name.equals("country")) {
        this.getCountry().remove(castToCodeableConcept(value));
      } else
        super.removeChild(name, value);
      
    }

    @Override
    public Base makeProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 530040176:
        return getSubstance();
      case 1791316033:
        return getStrength();
      case 1945341992:
        return getStrengthLowLimit();
      case 235437876:
        return getMeasurementPointElement();
      case 957831062:
        return addCountry();
      default:
        return super.makeProperty(hash, name);
      }

    }

    @Override
    public String[] getTypesForProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 530040176:
        /* substance */ return new String[] { "CodeableConcept" };
      case 1791316033:
        /* strength */ return new String[] { "Ratio" };
      case 1945341992:
        /* strengthLowLimit */ return new String[] { "Ratio" };
      case 235437876:
        /* measurementPoint */ return new String[] { "string" };
      case 957831062:
        /* country */ return new String[] { "CodeableConcept" };
      default:
        return super.getTypesForProperty(hash, name);
      }

    }

    @Override
    public Base addChild(String name) throws FHIRException {
      if (name.equals("substance")) {
        this.substance = new CodeableConcept();
        return this.substance;
      } else if (name.equals("strength")) {
        this.strength = new Ratio();
        return this.strength;
      } else if (name.equals("strengthLowLimit")) {
        this.strengthLowLimit = new Ratio();
        return this.strengthLowLimit;
      } else if (name.equals("measurementPoint")) {
        throw new FHIRException("Cannot call addChild on a singleton property MedicinalProductIngredient.measurementPoint");
      } else if (name.equals("country")) {
        return addCountry();
      } else
        return super.addChild(name);
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent copy() {
      MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent dst = new MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent();
      copyValues(dst);
      return dst;
    }

    public void copyValues(MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent dst) {
      super.copyValues(dst);
      dst.substance = substance == null ? null : substance.copy();
      dst.strength = strength == null ? null : strength.copy();
      dst.strengthLowLimit = strengthLowLimit == null ? null : strengthLowLimit.copy();
      dst.measurementPoint = measurementPoint == null ? null : measurementPoint.copy();
      if (country != null) {
        dst.country = new ArrayList<CodeableConcept>();
        for (CodeableConcept i : country)
          dst.country.add(i.copy());
      }
      ;
    }

    @Override
    public boolean equalsDeep(Base other_) {
      if (!super.equalsDeep(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent))
        return false;
      MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent o = (MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent) other_;
      return compareDeep(substance, o.substance, true) && compareDeep(strength, o.strength, true)
          && compareDeep(strengthLowLimit, o.strengthLowLimit, true)
          && compareDeep(measurementPoint, o.measurementPoint, true) && compareDeep(country, o.country, true);
    }

    @Override
    public boolean equalsShallow(Base other_) {
      if (!super.equalsShallow(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent))
        return false;
      MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent o = (MedicinalProductIngredientSpecifiedSubstanceStrengthReferenceStrengthComponent) other_;
      return compareValues(measurementPoint, o.measurementPoint, true);
    }

    public boolean isEmpty() {
      return super.isEmpty()
          && ca.uhn.fhir.util.ElementUtil.isEmpty(substance, strength, strengthLowLimit, measurementPoint, country);
    }

    public String fhirType() {
      return "MedicinalProductIngredient.specifiedSubstance.strength.referenceStrength";

    }

  }

  @Block()
  public static class MedicinalProductIngredientSubstanceComponent extends BackboneElement
      implements IBaseBackboneElement {
    /**
     * The ingredient substance.
     */
    @Child(name = "code", type = {
        CodeableConcept.class }, order = 1, min = 1, max = 1, modifier = false, summary = true)
    @Description(shortDefinition = "The ingredient substance", formalDefinition = "The ingredient substance.")
    protected CodeableConcept code;

    /**
     * Quantity of the substance or specified substance present in the manufactured
     * item or pharmaceutical product.
     */
    @Child(name = "strength", type = {
        MedicinalProductIngredientSpecifiedSubstanceStrengthComponent.class }, order = 2, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = true)
    @Description(shortDefinition = "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product", formalDefinition = "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product.")
    protected List<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent> strength;

    private static final long serialVersionUID = 1325868149L;

    /**
     * Constructor
     */
    public MedicinalProductIngredientSubstanceComponent() {
      super();
    }

    /**
     * Constructor
     */
    public MedicinalProductIngredientSubstanceComponent(CodeableConcept code) {
      super();
      this.code = code;
    }

    /**
     * @return {@link #code} (The ingredient substance.)
     */
    public CodeableConcept getCode() {
      if (this.code == null)
        if (Configuration.errorOnAutoCreate())
          throw new Error("Attempt to auto-create MedicinalProductIngredientSubstanceComponent.code");
        else if (Configuration.doAutoCreate())
          this.code = new CodeableConcept(); // cc
      return this.code;
    }

    public boolean hasCode() {
      return this.code != null && !this.code.isEmpty();
    }

    /**
     * @param value {@link #code} (The ingredient substance.)
     */
    public MedicinalProductIngredientSubstanceComponent setCode(CodeableConcept value) {
      this.code = value;
      return this;
    }

    /**
     * @return {@link #strength} (Quantity of the substance or specified substance
     *         present in the manufactured item or pharmaceutical product.)
     */
    public List<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent> getStrength() {
      if (this.strength == null)
        this.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
      return this.strength;
    }

    /**
     * @return Returns a reference to <code>this</code> for easy method chaining
     */
    public MedicinalProductIngredientSubstanceComponent setStrength(
        List<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent> theStrength) {
      this.strength = theStrength;
      return this;
    }

    public boolean hasStrength() {
      if (this.strength == null)
        return false;
      for (MedicinalProductIngredientSpecifiedSubstanceStrengthComponent item : this.strength)
        if (!item.isEmpty())
          return true;
      return false;
    }

    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent addStrength() { // 3
      MedicinalProductIngredientSpecifiedSubstanceStrengthComponent t = new MedicinalProductIngredientSpecifiedSubstanceStrengthComponent();
      if (this.strength == null)
        this.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
      this.strength.add(t);
      return t;
    }

    public MedicinalProductIngredientSubstanceComponent addStrength(
        MedicinalProductIngredientSpecifiedSubstanceStrengthComponent t) { // 3
      if (t == null)
        return this;
      if (this.strength == null)
        this.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
      this.strength.add(t);
      return this;
    }

    /**
     * @return The first repetition of repeating field {@link #strength}, creating
     *         it if it does not already exist
     */
    public MedicinalProductIngredientSpecifiedSubstanceStrengthComponent getStrengthFirstRep() {
      if (getStrength().isEmpty()) {
        addStrength();
      }
      return getStrength().get(0);
    }

    protected void listChildren(List<Property> children) {
      super.listChildren(children);
      children.add(new Property("code", "CodeableConcept", "The ingredient substance.", 0, 1, code));
      children.add(new Property("strength", "@MedicinalProductIngredient.specifiedSubstance.strength",
          "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product.",
          0, java.lang.Integer.MAX_VALUE, strength));
    }

    @Override
    public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
      switch (_hash) {
      case 3059181:
        /* code */ return new Property("code", "CodeableConcept", "The ingredient substance.", 0, 1, code);
      case 1791316033:
        /* strength */ return new Property("strength", "@MedicinalProductIngredient.specifiedSubstance.strength",
            "Quantity of the substance or specified substance present in the manufactured item or pharmaceutical product.",
            0, java.lang.Integer.MAX_VALUE, strength);
      default:
        return super.getNamedProperty(_hash, _name, _checkValid);
      }

    }

    @Override
    public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
      switch (hash) {
      case 3059181:
        /* code */ return this.code == null ? new Base[0] : new Base[] { this.code }; // CodeableConcept
      case 1791316033:
        /* strength */ return this.strength == null ? new Base[0]
            : this.strength.toArray(new Base[this.strength.size()]); // MedicinalProductIngredientSpecifiedSubstanceStrengthComponent
      default:
        return super.getProperty(hash, name, checkValid);
      }

    }

    @Override
    public Base setProperty(int hash, String name, Base value) throws FHIRException {
      switch (hash) {
      case 3059181: // code
        this.code = castToCodeableConcept(value); // CodeableConcept
        return value;
      case 1791316033: // strength
        this.getStrength().add((MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) value); // MedicinalProductIngredientSpecifiedSubstanceStrengthComponent
        return value;
      default:
        return super.setProperty(hash, name, value);
      }

    }

    @Override
    public Base setProperty(String name, Base value) throws FHIRException {
      if (name.equals("code")) {
        this.code = castToCodeableConcept(value); // CodeableConcept
      } else if (name.equals("strength")) {
        this.getStrength().add((MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) value);
      } else
        return super.setProperty(name, value);
      return value;
    }

  @Override
  public void removeChild(String name, Base value) throws FHIRException {
      if (name.equals("code")) {
        this.code = null;
      } else if (name.equals("strength")) {
        this.getStrength().remove((MedicinalProductIngredientSpecifiedSubstanceStrengthComponent) value);
      } else
        super.removeChild(name, value);
      
    }

    @Override
    public Base makeProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 3059181:
        return getCode();
      case 1791316033:
        return addStrength();
      default:
        return super.makeProperty(hash, name);
      }

    }

    @Override
    public String[] getTypesForProperty(int hash, String name) throws FHIRException {
      switch (hash) {
      case 3059181:
        /* code */ return new String[] { "CodeableConcept" };
      case 1791316033:
        /* strength */ return new String[] { "@MedicinalProductIngredient.specifiedSubstance.strength" };
      default:
        return super.getTypesForProperty(hash, name);
      }

    }

    @Override
    public Base addChild(String name) throws FHIRException {
      if (name.equals("code")) {
        this.code = new CodeableConcept();
        return this.code;
      } else if (name.equals("strength")) {
        return addStrength();
      } else
        return super.addChild(name);
    }

    public MedicinalProductIngredientSubstanceComponent copy() {
      MedicinalProductIngredientSubstanceComponent dst = new MedicinalProductIngredientSubstanceComponent();
      copyValues(dst);
      return dst;
    }

    public void copyValues(MedicinalProductIngredientSubstanceComponent dst) {
      super.copyValues(dst);
      dst.code = code == null ? null : code.copy();
      if (strength != null) {
        dst.strength = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceStrengthComponent>();
        for (MedicinalProductIngredientSpecifiedSubstanceStrengthComponent i : strength)
          dst.strength.add(i.copy());
      }
      ;
    }

    @Override
    public boolean equalsDeep(Base other_) {
      if (!super.equalsDeep(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSubstanceComponent))
        return false;
      MedicinalProductIngredientSubstanceComponent o = (MedicinalProductIngredientSubstanceComponent) other_;
      return compareDeep(code, o.code, true) && compareDeep(strength, o.strength, true);
    }

    @Override
    public boolean equalsShallow(Base other_) {
      if (!super.equalsShallow(other_))
        return false;
      if (!(other_ instanceof MedicinalProductIngredientSubstanceComponent))
        return false;
      MedicinalProductIngredientSubstanceComponent o = (MedicinalProductIngredientSubstanceComponent) other_;
      return true;
    }

    public boolean isEmpty() {
      return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(code, strength);
    }

    public String fhirType() {
      return "MedicinalProductIngredient.substance";

    }

  }

  /**
   * The identifier(s) of this Ingredient that are assigned by business processes
   * and/or used to refer to it when a direct URL reference to the resource itself
   * is not appropriate.
   */
  @Child(name = "identifier", type = {
      Identifier.class }, order = 0, min = 0, max = 1, modifier = false, summary = true)
  @Description(shortDefinition = "Identifier for the ingredient", formalDefinition = "The identifier(s) of this Ingredient that are assigned by business processes and/or used to refer to it when a direct URL reference to the resource itself is not appropriate.")
  protected Identifier identifier;

  /**
   * Ingredient role e.g. Active ingredient, excipient.
   */
  @Child(name = "role", type = { CodeableConcept.class }, order = 1, min = 1, max = 1, modifier = false, summary = true)
  @Description(shortDefinition = "Ingredient role e.g. Active ingredient, excipient", formalDefinition = "Ingredient role e.g. Active ingredient, excipient.")
  protected CodeableConcept role;

  /**
   * If the ingredient is a known or suspected allergen.
   */
  @Child(name = "allergenicIndicator", type = {
      BooleanType.class }, order = 2, min = 0, max = 1, modifier = false, summary = true)
  @Description(shortDefinition = "If the ingredient is a known or suspected allergen", formalDefinition = "If the ingredient is a known or suspected allergen.")
  protected BooleanType allergenicIndicator;

  /**
   * Manufacturer of this Ingredient.
   */
  @Child(name = "manufacturer", type = {
      Organization.class }, order = 3, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = true)
  @Description(shortDefinition = "Manufacturer of this Ingredient", formalDefinition = "Manufacturer of this Ingredient.")
  protected List<Reference> manufacturer;
  /**
   * The actual objects that are the target of the reference (Manufacturer of this
   * Ingredient.)
   */
  protected List<Organization> manufacturerTarget;

  /**
   * A specified substance that comprises this ingredient.
   */
  @Child(name = "specifiedSubstance", type = {}, order = 4, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = true)
  @Description(shortDefinition = "A specified substance that comprises this ingredient", formalDefinition = "A specified substance that comprises this ingredient.")
  protected List<MedicinalProductIngredientSpecifiedSubstanceComponent> specifiedSubstance;

  /**
   * The ingredient substance.
   */
  @Child(name = "substance", type = {}, order = 5, min = 0, max = 1, modifier = false, summary = true)
  @Description(shortDefinition = "The ingredient substance", formalDefinition = "The ingredient substance.")
  protected MedicinalProductIngredientSubstanceComponent substance;

  private static final long serialVersionUID = -1454686641L;

  /**
   * Constructor
   */
  public MedicinalProductIngredient() {
    super();
  }

  /**
   * Constructor
   */
  public MedicinalProductIngredient(CodeableConcept role) {
    super();
    this.role = role;
  }

  /**
   * @return {@link #identifier} (The identifier(s) of this Ingredient that are
   *         assigned by business processes and/or used to refer to it when a
   *         direct URL reference to the resource itself is not appropriate.)
   */
  public Identifier getIdentifier() {
    if (this.identifier == null)
      if (Configuration.errorOnAutoCreate())
        throw new Error("Attempt to auto-create MedicinalProductIngredient.identifier");
      else if (Configuration.doAutoCreate())
        this.identifier = new Identifier(); // cc
    return this.identifier;
  }

  public boolean hasIdentifier() {
    return this.identifier != null && !this.identifier.isEmpty();
  }

  /**
   * @param value {@link #identifier} (The identifier(s) of this Ingredient that
   *              are assigned by business processes and/or used to refer to it
   *              when a direct URL reference to the resource itself is not
   *              appropriate.)
   */
  public MedicinalProductIngredient setIdentifier(Identifier value) {
    this.identifier = value;
    return this;
  }

  /**
   * @return {@link #role} (Ingredient role e.g. Active ingredient, excipient.)
   */
  public CodeableConcept getRole() {
    if (this.role == null)
      if (Configuration.errorOnAutoCreate())
        throw new Error("Attempt to auto-create MedicinalProductIngredient.role");
      else if (Configuration.doAutoCreate())
        this.role = new CodeableConcept(); // cc
    return this.role;
  }

  public boolean hasRole() {
    return this.role != null && !this.role.isEmpty();
  }

  /**
   * @param value {@link #role} (Ingredient role e.g. Active ingredient,
   *              excipient.)
   */
  public MedicinalProductIngredient setRole(CodeableConcept value) {
    this.role = value;
    return this;
  }

  /**
   * @return {@link #allergenicIndicator} (If the ingredient is a known or
   *         suspected allergen.). This is the underlying object with id, value
   *         and extensions. The accessor "getAllergenicIndicator" gives direct
   *         access to the value
   */
  public BooleanType getAllergenicIndicatorElement() {
    if (this.allergenicIndicator == null)
      if (Configuration.errorOnAutoCreate())
        throw new Error("Attempt to auto-create MedicinalProductIngredient.allergenicIndicator");
      else if (Configuration.doAutoCreate())
        this.allergenicIndicator = new BooleanType(); // bb
    return this.allergenicIndicator;
  }

  public boolean hasAllergenicIndicatorElement() {
    return this.allergenicIndicator != null && !this.allergenicIndicator.isEmpty();
  }

  public boolean hasAllergenicIndicator() {
    return this.allergenicIndicator != null && !this.allergenicIndicator.isEmpty();
  }

  /**
   * @param value {@link #allergenicIndicator} (If the ingredient is a known or
   *              suspected allergen.). This is the underlying object with id,
   *              value and extensions. The accessor "getAllergenicIndicator"
   *              gives direct access to the value
   */
  public MedicinalProductIngredient setAllergenicIndicatorElement(BooleanType value) {
    this.allergenicIndicator = value;
    return this;
  }

  /**
   * @return If the ingredient is a known or suspected allergen.
   */
  public boolean getAllergenicIndicator() {
    return this.allergenicIndicator == null || this.allergenicIndicator.isEmpty() ? false
        : this.allergenicIndicator.getValue();
  }

  /**
   * @param value If the ingredient is a known or suspected allergen.
   */
  public MedicinalProductIngredient setAllergenicIndicator(boolean value) {
    if (this.allergenicIndicator == null)
      this.allergenicIndicator = new BooleanType();
    this.allergenicIndicator.setValue(value);
    return this;
  }

  /**
   * @return {@link #manufacturer} (Manufacturer of this Ingredient.)
   */
  public List<Reference> getManufacturer() {
    if (this.manufacturer == null)
      this.manufacturer = new ArrayList<Reference>();
    return this.manufacturer;
  }

  /**
   * @return Returns a reference to <code>this</code> for easy method chaining
   */
  public MedicinalProductIngredient setManufacturer(List<Reference> theManufacturer) {
    this.manufacturer = theManufacturer;
    return this;
  }

  public boolean hasManufacturer() {
    if (this.manufacturer == null)
      return false;
    for (Reference item : this.manufacturer)
      if (!item.isEmpty())
        return true;
    return false;
  }

  public Reference addManufacturer() { // 3
    Reference t = new Reference();
    if (this.manufacturer == null)
      this.manufacturer = new ArrayList<Reference>();
    this.manufacturer.add(t);
    return t;
  }

  public MedicinalProductIngredient addManufacturer(Reference t) { // 3
    if (t == null)
      return this;
    if (this.manufacturer == null)
      this.manufacturer = new ArrayList<Reference>();
    this.manufacturer.add(t);
    return this;
  }

  /**
   * @return The first repetition of repeating field {@link #manufacturer},
   *         creating it if it does not already exist
   */
  public Reference getManufacturerFirstRep() {
    if (getManufacturer().isEmpty()) {
      addManufacturer();
    }
    return getManufacturer().get(0);
  }

  /**
   * @deprecated Use Reference#setResource(IBaseResource) instead
   */
  @Deprecated
  public List<Organization> getManufacturerTarget() {
    if (this.manufacturerTarget == null)
      this.manufacturerTarget = new ArrayList<Organization>();
    return this.manufacturerTarget;
  }

  /**
   * @deprecated Use Reference#setResource(IBaseResource) instead
   */
  @Deprecated
  public Organization addManufacturerTarget() {
    Organization r = new Organization();
    if (this.manufacturerTarget == null)
      this.manufacturerTarget = new ArrayList<Organization>();
    this.manufacturerTarget.add(r);
    return r;
  }

  /**
   * @return {@link #specifiedSubstance} (A specified substance that comprises
   *         this ingredient.)
   */
  public List<MedicinalProductIngredientSpecifiedSubstanceComponent> getSpecifiedSubstance() {
    if (this.specifiedSubstance == null)
      this.specifiedSubstance = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceComponent>();
    return this.specifiedSubstance;
  }

  /**
   * @return Returns a reference to <code>this</code> for easy method chaining
   */
  public MedicinalProductIngredient setSpecifiedSubstance(
      List<MedicinalProductIngredientSpecifiedSubstanceComponent> theSpecifiedSubstance) {
    this.specifiedSubstance = theSpecifiedSubstance;
    return this;
  }

  public boolean hasSpecifiedSubstance() {
    if (this.specifiedSubstance == null)
      return false;
    for (MedicinalProductIngredientSpecifiedSubstanceComponent item : this.specifiedSubstance)
      if (!item.isEmpty())
        return true;
    return false;
  }

  public MedicinalProductIngredientSpecifiedSubstanceComponent addSpecifiedSubstance() { // 3
    MedicinalProductIngredientSpecifiedSubstanceComponent t = new MedicinalProductIngredientSpecifiedSubstanceComponent();
    if (this.specifiedSubstance == null)
      this.specifiedSubstance = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceComponent>();
    this.specifiedSubstance.add(t);
    return t;
  }

  public MedicinalProductIngredient addSpecifiedSubstance(MedicinalProductIngredientSpecifiedSubstanceComponent t) { // 3
    if (t == null)
      return this;
    if (this.specifiedSubstance == null)
      this.specifiedSubstance = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceComponent>();
    this.specifiedSubstance.add(t);
    return this;
  }

  /**
   * @return The first repetition of repeating field {@link #specifiedSubstance},
   *         creating it if it does not already exist
   */
  public MedicinalProductIngredientSpecifiedSubstanceComponent getSpecifiedSubstanceFirstRep() {
    if (getSpecifiedSubstance().isEmpty()) {
      addSpecifiedSubstance();
    }
    return getSpecifiedSubstance().get(0);
  }

  /**
   * @return {@link #substance} (The ingredient substance.)
   */
  public MedicinalProductIngredientSubstanceComponent getSubstance() {
    if (this.substance == null)
      if (Configuration.errorOnAutoCreate())
        throw new Error("Attempt to auto-create MedicinalProductIngredient.substance");
      else if (Configuration.doAutoCreate())
        this.substance = new MedicinalProductIngredientSubstanceComponent(); // cc
    return this.substance;
  }

  public boolean hasSubstance() {
    return this.substance != null && !this.substance.isEmpty();
  }

  /**
   * @param value {@link #substance} (The ingredient substance.)
   */
  public MedicinalProductIngredient setSubstance(MedicinalProductIngredientSubstanceComponent value) {
    this.substance = value;
    return this;
  }

  protected void listChildren(List<Property> children) {
    super.listChildren(children);
    children.add(new Property("identifier", "Identifier",
        "The identifier(s) of this Ingredient that are assigned by business processes and/or used to refer to it when a direct URL reference to the resource itself is not appropriate.",
        0, 1, identifier));
    children
        .add(new Property("role", "CodeableConcept", "Ingredient role e.g. Active ingredient, excipient.", 0, 1, role));
    children.add(new Property("allergenicIndicator", "boolean", "If the ingredient is a known or suspected allergen.",
        0, 1, allergenicIndicator));
    children.add(new Property("manufacturer", "Reference(Organization)", "Manufacturer of this Ingredient.", 0,
        java.lang.Integer.MAX_VALUE, manufacturer));
    children.add(new Property("specifiedSubstance", "", "A specified substance that comprises this ingredient.", 0,
        java.lang.Integer.MAX_VALUE, specifiedSubstance));
    children.add(new Property("substance", "", "The ingredient substance.", 0, 1, substance));
  }

  @Override
  public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
    switch (_hash) {
    case -1618432855:
      /* identifier */ return new Property("identifier", "Identifier",
          "The identifier(s) of this Ingredient that are assigned by business processes and/or used to refer to it when a direct URL reference to the resource itself is not appropriate.",
          0, 1, identifier);
    case 3506294:
      /* role */ return new Property("role", "CodeableConcept", "Ingredient role e.g. Active ingredient, excipient.", 0,
          1, role);
    case 75406931:
      /* allergenicIndicator */ return new Property("allergenicIndicator", "boolean",
          "If the ingredient is a known or suspected allergen.", 0, 1, allergenicIndicator);
    case -1969347631:
      /* manufacturer */ return new Property("manufacturer", "Reference(Organization)",
          "Manufacturer of this Ingredient.", 0, java.lang.Integer.MAX_VALUE, manufacturer);
    case -331477600:
      /* specifiedSubstance */ return new Property("specifiedSubstance", "",
          "A specified substance that comprises this ingredient.", 0, java.lang.Integer.MAX_VALUE, specifiedSubstance);
    case 530040176:
      /* substance */ return new Property("substance", "", "The ingredient substance.", 0, 1, substance);
    default:
      return super.getNamedProperty(_hash, _name, _checkValid);
    }

  }

  @Override
  public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
    switch (hash) {
    case -1618432855:
      /* identifier */ return this.identifier == null ? new Base[0] : new Base[] { this.identifier }; // Identifier
    case 3506294:
      /* role */ return this.role == null ? new Base[0] : new Base[] { this.role }; // CodeableConcept
    case 75406931:
      /* allergenicIndicator */ return this.allergenicIndicator == null ? new Base[0]
          : new Base[] { this.allergenicIndicator }; // BooleanType
    case -1969347631:
      /* manufacturer */ return this.manufacturer == null ? new Base[0]
          : this.manufacturer.toArray(new Base[this.manufacturer.size()]); // Reference
    case -331477600:
      /* specifiedSubstance */ return this.specifiedSubstance == null ? new Base[0]
          : this.specifiedSubstance.toArray(new Base[this.specifiedSubstance.size()]); // MedicinalProductIngredientSpecifiedSubstanceComponent
    case 530040176:
      /* substance */ return this.substance == null ? new Base[0] : new Base[] { this.substance }; // MedicinalProductIngredientSubstanceComponent
    default:
      return super.getProperty(hash, name, checkValid);
    }

  }

  @Override
  public Base setProperty(int hash, String name, Base value) throws FHIRException {
    switch (hash) {
    case -1618432855: // identifier
      this.identifier = castToIdentifier(value); // Identifier
      return value;
    case 3506294: // role
      this.role = castToCodeableConcept(value); // CodeableConcept
      return value;
    case 75406931: // allergenicIndicator
      this.allergenicIndicator = castToBoolean(value); // BooleanType
      return value;
    case -1969347631: // manufacturer
      this.getManufacturer().add(castToReference(value)); // Reference
      return value;
    case -331477600: // specifiedSubstance
      this.getSpecifiedSubstance().add((MedicinalProductIngredientSpecifiedSubstanceComponent) value); // MedicinalProductIngredientSpecifiedSubstanceComponent
      return value;
    case 530040176: // substance
      this.substance = (MedicinalProductIngredientSubstanceComponent) value; // MedicinalProductIngredientSubstanceComponent
      return value;
    default:
      return super.setProperty(hash, name, value);
    }

  }

  @Override
  public Base setProperty(String name, Base value) throws FHIRException {
    if (name.equals("identifier")) {
      this.identifier = castToIdentifier(value); // Identifier
    } else if (name.equals("role")) {
      this.role = castToCodeableConcept(value); // CodeableConcept
    } else if (name.equals("allergenicIndicator")) {
      this.allergenicIndicator = castToBoolean(value); // BooleanType
    } else if (name.equals("manufacturer")) {
      this.getManufacturer().add(castToReference(value));
    } else if (name.equals("specifiedSubstance")) {
      this.getSpecifiedSubstance().add((MedicinalProductIngredientSpecifiedSubstanceComponent) value);
    } else if (name.equals("substance")) {
      this.substance = (MedicinalProductIngredientSubstanceComponent) value; // MedicinalProductIngredientSubstanceComponent
    } else
      return super.setProperty(name, value);
    return value;
  }

  @Override
  public void removeChild(String name, Base value) throws FHIRException {
    if (name.equals("identifier")) {
      this.identifier = null;
    } else if (name.equals("role")) {
      this.role = null;
    } else if (name.equals("allergenicIndicator")) {
      this.allergenicIndicator = null;
    } else if (name.equals("manufacturer")) {
      this.getManufacturer().remove(castToReference(value));
    } else if (name.equals("specifiedSubstance")) {
      this.getSpecifiedSubstance().remove((MedicinalProductIngredientSpecifiedSubstanceComponent) value);
    } else if (name.equals("substance")) {
      this.substance = (MedicinalProductIngredientSubstanceComponent) value; // MedicinalProductIngredientSubstanceComponent
    } else
      super.removeChild(name, value);
    
  }

  @Override
  public Base makeProperty(int hash, String name) throws FHIRException {
    switch (hash) {
    case -1618432855:
      return getIdentifier();
    case 3506294:
      return getRole();
    case 75406931:
      return getAllergenicIndicatorElement();
    case -1969347631:
      return addManufacturer();
    case -331477600:
      return addSpecifiedSubstance();
    case 530040176:
      return getSubstance();
    default:
      return super.makeProperty(hash, name);
    }

  }

  @Override
  public String[] getTypesForProperty(int hash, String name) throws FHIRException {
    switch (hash) {
    case -1618432855:
      /* identifier */ return new String[] { "Identifier" };
    case 3506294:
      /* role */ return new String[] { "CodeableConcept" };
    case 75406931:
      /* allergenicIndicator */ return new String[] { "boolean" };
    case -1969347631:
      /* manufacturer */ return new String[] { "Reference" };
    case -331477600:
      /* specifiedSubstance */ return new String[] {};
    case 530040176:
      /* substance */ return new String[] {};
    default:
      return super.getTypesForProperty(hash, name);
    }

  }

  @Override
  public Base addChild(String name) throws FHIRException {
    if (name.equals("identifier")) {
      this.identifier = new Identifier();
      return this.identifier;
    } else if (name.equals("role")) {
      this.role = new CodeableConcept();
      return this.role;
    } else if (name.equals("allergenicIndicator")) {
      throw new FHIRException(
          "Cannot call addChild on a singleton property MedicinalProductIngredient.allergenicIndicator");
    } else if (name.equals("manufacturer")) {
      return addManufacturer();
    } else if (name.equals("specifiedSubstance")) {
      return addSpecifiedSubstance();
    } else if (name.equals("substance")) {
      this.substance = new MedicinalProductIngredientSubstanceComponent();
      return this.substance;
    } else
      return super.addChild(name);
  }

  public String fhirType() {
    return "MedicinalProductIngredient";

  }

  public MedicinalProductIngredient copy() {
    MedicinalProductIngredient dst = new MedicinalProductIngredient();
    copyValues(dst);
    return dst;
  }

  public void copyValues(MedicinalProductIngredient dst) {
    super.copyValues(dst);
    dst.identifier = identifier == null ? null : identifier.copy();
    dst.role = role == null ? null : role.copy();
    dst.allergenicIndicator = allergenicIndicator == null ? null : allergenicIndicator.copy();
    if (manufacturer != null) {
      dst.manufacturer = new ArrayList<Reference>();
      for (Reference i : manufacturer)
        dst.manufacturer.add(i.copy());
    }
    ;
    if (specifiedSubstance != null) {
      dst.specifiedSubstance = new ArrayList<MedicinalProductIngredientSpecifiedSubstanceComponent>();
      for (MedicinalProductIngredientSpecifiedSubstanceComponent i : specifiedSubstance)
        dst.specifiedSubstance.add(i.copy());
    }
    ;
    dst.substance = substance == null ? null : substance.copy();
  }

  protected MedicinalProductIngredient typedCopy() {
    return copy();
  }

  @Override
  public boolean equalsDeep(Base other_) {
    if (!super.equalsDeep(other_))
      return false;
    if (!(other_ instanceof MedicinalProductIngredient))
      return false;
    MedicinalProductIngredient o = (MedicinalProductIngredient) other_;
    return compareDeep(identifier, o.identifier, true) && compareDeep(role, o.role, true)
        && compareDeep(allergenicIndicator, o.allergenicIndicator, true)
        && compareDeep(manufacturer, o.manufacturer, true)
        && compareDeep(specifiedSubstance, o.specifiedSubstance, true) && compareDeep(substance, o.substance, true);
  }

  @Override
  public boolean equalsShallow(Base other_) {
    if (!super.equalsShallow(other_))
      return false;
    if (!(other_ instanceof MedicinalProductIngredient))
      return false;
    MedicinalProductIngredient o = (MedicinalProductIngredient) other_;
    return compareValues(allergenicIndicator, o.allergenicIndicator, true);
  }

  public boolean isEmpty() {
    return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(identifier, role, allergenicIndicator, manufacturer,
        specifiedSubstance, substance);
  }

  @Override
  public ResourceType getResourceType() {
    return ResourceType.MedicinalProductIngredient;
  }

}